﻿using PhotoGallery.Models;
using PhotoGallery.Models.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Helpers;
using System.Web.Hosting;
using System.Web.Mvc;
using PagedList;
using System.IO;
using Lib.Web.Mvc;
using PhotoGallery.Models.Utils;

namespace PhotoGallery.Controllers
{
    [Authorize]
    public class VideoController : BaseController
    {
        public ActionResult Index(int? albumID)
        {
            if (albumID == null)
            {
                return RedirectToAction("Index", "Albums");
            }
            return RedirectToAction("List");
        }

        public ActionResult Details(int? id, int? albumID)
        {
            if (albumID == null)
            {
                return RedirectToAction("Index", "Albums");
            }
            if (!id.HasValue)
            {
                return RedirectToAction("Index");
            }
            
            AlbumInfo album = new AlbumsModel().Get(albumID ?? default(int));
            VideoModel model = new VideoModel(album);
            return View(model.Get(id ?? default(int)));
        }

        public ActionResult Create()
        {
            if (Request.UrlReferrer != null)
            {
                TempData["backUrl"] = Request.UrlReferrer.ToString();
                ViewBag.backUrl = Request.UrlReferrer.ToString();
            }
            else
            {
                ViewBag.backUrl = Url.Action("Index");
            }

            return View(new VideoViewModel());
        }

        [HttpPost]
        public ActionResult Create(VideoViewModel viewModel, int albumID, HttpPostedFileBase[] files, HttpPostedFileBase thummnail)
        {
            ViewBag.backUrl = TempData["backUrl"];
            TempData.Keep();
            if (files.FirstOrDefault() != null)
            {
                AlbumInfo album = new AlbumsModel().Get(albumID);
                VideoModel model = new VideoModel(album);
                foreach (HttpPostedFileBase file in files)
                {
                    if (FileValidation.IsValid(file, new List<string>(){
                            ".mp4", ".m4v", ".ogv", ".webm", ".avi"
                    }))
                    {
                        model.Create(viewModel.Video, file, thummnail);
                    }
                }
                return RedirectToAction("List");
            }
            else
            {
                ModelState.AddModelError("", "No files");
            }

            return View(viewModel);
        }

        public ActionResult Edit(int? id, int? albumID, string backUrl)
        {
            if (albumID == null)
            {
                return RedirectToAction("Index", "Albums");
            }
            if (!id.HasValue)
            {
                return RedirectToAction("Index");
            }
            if (String.IsNullOrEmpty(backUrl))
            {
                if (Request.UrlReferrer != null)
                {
                    backUrl = Request.UrlReferrer.ToString();
                }
            }
            TempData["backUrl"] = backUrl;
            TempData.Keep();

            ViewBag.backUrl = backUrl;

            VideoViewModel viewModel = new VideoViewModel();
            viewModel.Album = new AlbumsModel().Get(albumID ?? default(int));
            
            VideoModel model = new VideoModel(viewModel.Album);
            viewModel.Video = model.Get(id ?? default(int));
            viewModel.VideoAttachments = model.GetAttachments(id ?? default(int));

            ViewBag.Attachments = model.GetAttachments(id ?? default(int));
            if (viewModel.Video == null)
                return RedirectToAction("Index");


            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Edit(VideoViewModel viewModel, HttpPostedFileBase file, HttpPostedFileBase file1, int albumID)
        {
            ViewBag.backUrl = TempData["backUrl"];
            TempData.Keep();
            if (ModelState.IsValid)
            {
                try
                {
                    AlbumInfo album = new AlbumsModel().Get(albumID);
                    VideoModel model = new VideoModel(album);
                    bool valid = true;
                    if (file != null)
                    {
                        if (FileValidation.IsValid(file, new List<string>(){
                            ".mp4", ".m4v", ".ogv", ".webm", ".avi"
                        }))
                        {
                            valid = true;
                        }
                        else
                        {
                            valid = false;
                        }
                    }
                    if (file1 != null)
                    {
                        if (FileValidation.IsValid(file1, new List<string>(){
                            ".mp4", ".m4v", ".ogv", ".webm", ".avi"
                        }))
                        {
                            valid = true;
                        }
                        else
                        {
                            valid = false;
                        }
                    }
                    if (valid)
                    {
                        model.Update(viewModel.Video, file, file1);
                        return RedirectToAction("Index");
                    }
                    else
                    {
                        ModelState.AddModelError("", "invalid file. ");
                    }
                    
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", "Error editing record. " + ex.Message);
                }
            }

            return View(viewModel);
        }

        public ActionResult VideoAttachments(IEnumerable<VideoAttacumentsInfo> Attachments, string returnUrl, int videoID)
        {
            ViewBag.ReturnUrl = returnUrl;
            ViewBag.VideoID = videoID;
            return PartialView("_VideoAttachments", Attachments);
        }

        public ActionResult Delete(int? id, int? albumID)
        {
            if (albumID == null)
            {
                return RedirectToAction("Index", "Albums");
            }
            if (!id.HasValue)
            {
                return RedirectToAction("Index");
            }

            AlbumInfo album = new AlbumsModel().Get(albumID ?? default(int));
            VideoModel model = new VideoModel(album);
            VideoInfo video = model.Get(id ?? default(int));
            if (video == null)
                return RedirectToAction("Index");

            return View(video);
        }

        [HttpPost]
        public ActionResult Delete(int albumID, VideoInfo video)
        {
            AlbumInfo album = new AlbumsModel().Get(albumID);
            VideoModel model = new VideoModel(album);

            try
            {
                model.Delete(video);
                return RedirectToAction("Index");
            }
            catch (Exception ex)
            {
                ViewBag.ErrorMsg = "Error deleting record. " + ex.Message;
                return View(video);
            }
        }

        public ActionResult Show(int? id, int? albumId)
        {
            ViewBag.AlbumID = albumId;

            AlbumInfo album = new AlbumsModel().Get(albumId ?? default(int));
            VideoModel model = new VideoModel(album);
            VideoViewModel viewModel = new VideoViewModel();
            viewModel.Video = model.Get(id ?? 1);
            if (viewModel.Video == null)
            {
                return RedirectToAction("Index");
            }
            viewModel.Videos = model.Get();
            VideoAttacmentModel amodel = new VideoAttacmentModel(albumId ?? default(int), id ?? default(int));
            viewModel.VideoAttachments = amodel.Get(); 
            return View(viewModel);
        }

        public ActionResult List(int? albumID, int? page)
        {
            VideoViewModel viewModel = new VideoViewModel();
            viewModel.Album = new AlbumsModel().Get(albumID ?? default(int));
            viewModel.Videos = new VideoModel(viewModel.Album).Get(); 
                        
            var pageNumber = page ?? 1;
            var onePageOfProducts = viewModel.Videos.ToPagedList(pageNumber, Tune.ItemsPerPage); 

            ViewBag.OnePageOfProducts = onePageOfProducts;
            return View(viewModel);
        }

        public ActionResult DownloadVideo(string file = "", string mimeType="")
        {
            if (Request.UserAgent.Contains("MSIE"))
            {
                return DownloadVideoIE(file);
            }
            else
            {
                return DownloadChrom(file);
            }
        }


        [HttpPost]
        public ActionResult Disassociate(int id, int albumID, int videoID)
        {
            object url;
            TempData.TryGetValue("backUrl", out url);
            TempData.Keep();

            VideoAttacmentModel model = new VideoAttacmentModel(albumID, videoID);
            model.Delete(id);
            return RedirectToAction("Edit", new { id = videoID, backUrl = url.ToString() });
        }

        [HttpPost]
        public ActionResult Associate(VideoAttacumentsInfo video,  HttpPostedFileBase file1, int albumID, int videoID)
        {
            object url;
            TempData.TryGetValue("backUrl", out url);
            TempData.Keep();

            VideoAttacmentModel model = new VideoAttacmentModel(albumID, videoID);
            model.Create(video,file1);
            return RedirectToAction("Edit", new { id = videoID, backUrl = url.ToString() });
        }

        #region private methods

        private ActionResult DownloadVideoIE(string file = "")
        {
            var fileStream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite);
            var mimeType = "video/mp4";
            string ext = Path.GetExtension(file);

            var fileDownloadName = Path.GetFileName(file);
            switch (ext)
            {
                case ".webm":
                    mimeType = "video/webm";
                    return File(fileStream, mimeType, fileDownloadName);
                case ".ogv":
                    mimeType = "video/ogg";
                    return File(fileStream, mimeType, fileDownloadName);
                default:
                    mimeType = "video/mp4";
                    return File(fileStream, mimeType, fileDownloadName);
            }
        }

        private RangeFilePathResult DownloadChrom(string file = "")
        {
            string ext = Path.GetExtension(file).ToLower();
            FileInfo oceansClipInfo = null;
            string type;
            switch (ext)
            {
                case ".webm":
                    type = "webm";
                    break;
                case ".ogv":
                    type = "ogg";
                    break;
                default:
                    type = "mp4";
                    break;
            }
            string oceansClipMimeType = String.Format("video/{0}", type);

            switch (ext)
            {
                case ".mp4":
                    oceansClipInfo = new FileInfo(file);
                    break;
                case ".webm":
                    oceansClipInfo = new FileInfo(file);
                    break;
                case ".ogg":
                    oceansClipInfo = new FileInfo(file);
                    break;
            }

            return new RangeFilePathResult(oceansClipMimeType, oceansClipInfo.FullName, oceansClipInfo.LastWriteTimeUtc, oceansClipInfo.Length);
        }

        #endregion
    }
}
